package com.mybatis.util;

import com.mybatis.dao.Adao;

import java.lang.reflect.Field;
import java.lang.reflect.Modifier;
import java.lang.reflect.ParameterizedType;
import java.lang.reflect.Type;
import java.util.*;

public class MyReflectionUtils {
    //获取泛型父类的第一个泛型的真是类型
    public static Class<?> extractModelClass(Class<?> mapperClass)
    {
        //这里就考虑到只有一个泛型父类，即basecruddao，如果多个，就返回type数组了,因为是接口，还是得返回数组
        Type[] t = mapperClass.getGenericInterfaces();
        //为了不改变数组内容，这边赋值一个数字给他
        Type[] parameters = t;
        ParameterizedType type = null;
        type =(ParameterizedType)parameters[0];
        return (Class<?>) type.getActualTypeArguments()[0];

    }

    public static List<Field> getAllFieldsExcludeTransient(Class<?> modelClass) {
        List<Field> fieldList = new ArrayList<>();
        List<Field> fields = getAllFiledsIncludeParent(modelClass);
        Iterator iterator = fields.iterator();
        //如果用iterator可以只用一个数组，在遍历的时候就可以remove，for each则不行
        while (iterator.hasNext())
        {
            Field field = (Field) iterator.next();
            if (!Modifier.isTransient(field.getModifiers()))
            {
                fieldList.add(field);
            }
        }
        return fieldList;
    }
    //通过迭代器方法获取当前类包括父类所有的公有私有属性
    private static List<Field> getAllFiledsIncludeParent(Class<?> modelClass) {
        List<Field> fieldList = new ArrayList<>();
        Field[] fields = modelClass.getDeclaredFields();//此方法仅仅返回本类的
        Collections.addAll(fieldList,fields);//因为返回的是数组，所以只能用工具类
        if (modelClass.getSuperclass()==Object.class)
        {
            return fieldList;
        }
        else {
             fieldList.addAll(getAllFiledsIncludeParent(modelClass.getSuperclass()));
             return fieldList;
        }
    }

//    public static void main(TestString[] args) {
//        System.out.println(extractModelClass(Adao.class));//成功取出泛型类
//    }
}
